package com.yu.waterstation.app.moudles.address.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.yu.waterstation.app.moudles.address.mapper.AddressMapper;
import com.yu.waterstation.common.entity.app.Address;
import com.yu.waterstation.common.entity.app.Student;
import com.yu.waterstation.common.entity.app.dto.AddressDTO;
import com.yu.waterstation.app.moudles.student.mapper.StudentMapper;
import com.yu.waterstation.common.common.constant.Const;
import com.yu.waterstation.common.service.RedisService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

@Slf4j
@Service
public class AddressServiceImpl implements AddressService {
    @Resource
    private AddressMapper addressMapper;

    @Resource
    private StudentMapper studentMapper;

    @Resource
    private RedisService redisService;

    // TODO 本地缓存, 地址选择树
    private static Map<String, List<Address>> addressTreeCache;

    @Override
    public AddressDTO getAddressDetail(Integer id) {
        Address address = addressMapper.selectById(id);
        List<Student> studentList = studentMapper.selectList(new QueryWrapper<Student>().eq("address_id", id));
        AddressDTO addressDTO = new AddressDTO();
        BeanUtils.copyProperties(address, addressDTO);
        addressDTO.setStudentList(studentList); // 宿舍成员
        return addressDTO;
    }

    @Override
    public Map<String, List<Address>> getAddressTree() {
        // 拉取缓存
        boolean flag = redisService.hasKey(Const.CONST_address_tree_flag);
        if (flag && !CollectionUtils.isEmpty(addressTreeCache))
            return addressTreeCache;

        addressTreeCache = generateAddressTree();
        redisService.set(Const.CONST_address_tree_flag, "true", Const.CONST_one_day);
        return addressTreeCache;
    }

    private synchronized Map<String, List<Address>> generateAddressTree() {
        Map<String, List<Address>> tree = new TreeMap<>();
        List<Address> list = addressMapper.selectList(new QueryWrapper<Address>()
                .orderByAsc("dorm", "room" ));
        // 生成地址树 eg: 遍历到二区15舍309时
        for (Address address : list) {
            if (!tree.containsKey(address.getDorm()))  // eg: 不存在二区15舍则创建
                tree.put(address.getDorm(), new ArrayList<>());

            // eg: 进入二区15舍范围  {"15舍": [308,310], "16舍": [309]}
            tree.get(address.getDorm()).add(address);
        }
        return tree;
    }

    @Override
    public List<Object> getAllDorms() {
        return addressMapper.selectObjs(new QueryWrapper<Address>()
                .select("dorm" )
                .groupBy("dorm" ));
    }

}
